package cn.cnlee.app.remote.response;

import androidx.annotation.NonNull;

import org.reactivestreams.Publisher;

import cn.cnlee.app.config.Constants;
import cn.cnlee.app.remote.exception.ClientException;
import cn.cnlee.app.remote.exception.ServiceException;
import cn.cnlee.app.util.StringUtil;
import io.reactivex.BackpressureStrategy;
import io.reactivex.Flowable;
import io.reactivex.FlowableEmitter;
import io.reactivex.FlowableOnSubscribe;
import io.reactivex.FlowableTransformer;
import io.reactivex.Observable;
import io.reactivex.ObservableSource;
import io.reactivex.ObservableTransformer;
import io.reactivex.functions.Function;
import retrofit2.Response;

/**
 * 对返回的数据进行处理，区分异常的情况
 */
public class ResponseTransformer {

    /**
     * 预处理  code处理
     *
     * @param <T>
     * @return
     */
    public static <T> FlowableTransformer<ResponseMsg<T>, T> handleFlowableResult() {
        return new FlowableTransformer<ResponseMsg<T>, T>() {
            @Override
            public Publisher<T> apply(Flowable<ResponseMsg<T>> upstream) {
                return upstream.flatMap(new Function<ResponseMsg<T>, Flowable<T>>() {
                    @Override
                    public Flowable<T> apply(@NonNull ResponseMsg<T> responseMsg) throws Exception {
                        if (responseMsg.isOk()) {
                            return createData(responseMsg.getReturnValue());
                        } else if (responseMsg.getCode() == Code.NEED_LOGIN_CODE) {
                            return Flowable.error(new ServiceException(Constants.TO_LOGIN_CODE, "请先登陆！"));
                        } else if (responseMsg.getCode() == Code.CHECK_SMS_CODE) {
                            return Flowable.error(new ServiceException(Constants.TO_CHECK_SMS_CODE, "已经在其他地方登录！"));
                        } else {
                            return Flowable.error(new ServiceException(ClientException.UNKNOWN, StringUtil.sBlank(responseMsg.getMessage(), "服务器出错了")));
                        }
                    }
                });
            }
        };
    }

    /**
     * 生成Flowable
     *
     * @param <T>
     * @return
     */
    public static <T> Flowable<T> createData(final T t) {
        return Flowable.create(new FlowableOnSubscribe<T>() {
            @Override
            public void subscribe(FlowableEmitter<T> emitter) {
                try {
                    emitter.onNext(t);
                    emitter.onComplete();
                } catch (Exception e) {
                    emitter.onError(e);
                }
            }
        }, BackpressureStrategy.BUFFER);
    }

//    /**
//     * 生成Flowable
//     *
//     * @param <T>
//     * @return
//     */
//    public static <T> Flowable<T> quickLogin(final T t) {
//        return Flowable.create(new FlowableOnSubscribe<T>() {
//            @Override
//            public void subscribe(FlowableEmitter<T> emitter) {
////                emitter.onError(new ServiceException(-1, "请先登陆"));
//                Logger.e("=========快速登录=======");
//                RemoteClient.getInstance().create(ApiService.class).getDemoData(new EmptyVo())
//                        .compose(ResponseTransformer.handleFlowableResult())
//                        .compose(RxSchedulers.io_main())
//                        .subscribe(new RxSubscriber<IndexDTO>() {
//                            @Override
//                            public void onSuccess(IndexDTO indexDTO) {
//                                Logger.e("=========登录成功=======");
//                                emitter.onNext(t);
//                            }
//
//                            @Override
//                            public void onFailure(String msg, int code) {
//                                emitter.onError(new ServiceException(-2, "请先登陆"));
//                            }
//                        });
//
//            }
//        }, BackpressureStrategy.BUFFER);
//    }

    public static <T> ObservableTransformer<Response<T>, T> handleObservableResult() {
        return upstream -> upstream
                .onErrorResumeNext(new ErrorResumeFunction<>())
                .flatMap(new ResponseFunction<>());
    }


    /**
     * 非服务器产生的异常，比如本地无无网络请求，Json数据解析错误等等。
     *
     * @param <T>
     */
    private static class ErrorResumeFunction<T> implements Function<Throwable, ObservableSource<? extends Response<T>>> {

        @Override
        public ObservableSource<? extends Response<T>> apply(Throwable throwable) throws Exception {
            return Observable.error(ClientException.handleException(throwable));
        }
    }

    /**
     * 服务其返回的数据解析
     * 正常服务器返回数据和服务器可能返回的exception
     *
     * @param <T>
     */
    private static class ResponseFunction<T> implements Function<Response<T>, ObservableSource<T>> {

        @Override
        public ObservableSource<T> apply(Response<T> response) {
            int code = response.code();
            String message = response.message();
            if (code == 200) {
                assert response.body() != null;
                return Observable.just(response.body());
            } else {
                return Observable.error(new ServiceException(code, message));
            }
        }
    }
}
